package com.douyang.handle;

import com.alibaba.fastjson.JSONObject;
import com.douyang.base.model.UserBaseInfo;
import com.douyang.base.utils.UserUtil;
import com.douyang.config.SpringBeanContext;
import jakarta.websocket.OnClose;
import jakarta.websocket.OnMessage;
import jakarta.websocket.OnOpen;
import jakarta.websocket.Session;
import jakarta.websocket.server.PathParam;
import jakarta.websocket.server.ServerEndpoint;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.WebSocketSession;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

@Component
@ServerEndpoint("/ws/{roomId}/{token}")
public class WebSocketServer {


    //存放会话对象   roomId  userId
    private static Map<Long, Map<Long,Session>> sessionMap = new ConcurrentHashMap<>();

    /**
     * 连接建立成功调用的方法
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("roomId") Long roomId,@PathParam("token")String token) {
        Long userId = UserUtil.getLoginUserBaseInfo(token).getId();
        sessionMap.computeIfAbsent(roomId, k -> new HashMap<>());
        sessionMap.get(roomId).put(userId, session);
        StringRedisTemplate stringRedisTemplate = SpringBeanContext.getContext().getBean(StringRedisTemplate.class);
        stringRedisTemplate.opsForZSet().addIfAbsent(roomId.toString(),userId.toString(),0);
        sendToAllClient(null,roomId,null,null,2);
    }

    /**
     * 收到客户端消息后调用的方法
     *
     * @param message 客户端发送过来的消息
     */
    @OnMessage
    public void onMessage(String message, @PathParam("roomId") Long roomId,@PathParam("token")String token) {
        UserBaseInfo loginUserBaseInfo = UserUtil.getLoginUserBaseInfo(token);
        sendToAllClient(message,roomId,loginUserBaseInfo.getId(),loginUserBaseInfo.getUserName(),1);
    }

    /**
     * 连接关闭调用的方法
     *
     * @param roomId
     */
    @OnClose
    public void onClose(@PathParam("roomId") Long roomId,@PathParam("token")String  token) {
        UserBaseInfo loginUserBaseInfo = UserUtil.getLoginUserBaseInfo(token);
        sessionMap.get(roomId).remove(loginUserBaseInfo.getId());
        sendToAllClient(null,roomId,loginUserBaseInfo.getId(),null,3);
    }

    /**
     * 群发
     *
     * @param message
     */
    public void sendToAllClient(String message,Long roomId,Long loginUserId,String userName,Integer type) {
        Collection<Session> sessions = sessionMap.get(roomId).values();
        for (Session session : sessions) {
            try {
                //服务器向客户端发送消息
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("userId", loginUserId);
                jsonObject.put("userName", userName);
                jsonObject.put("content", message);
                jsonObject.put("type", type);    //1、消息 2、有人加入 3、有人退出(id) 4 有人点赞(id)
                session.getBasicRemote().sendText(jsonObject.toJSONString());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public Set<Long> getUserIdSet(Long roomId) {
        Map<Long, Session> longSessionMap = sessionMap.get(roomId);
        if (longSessionMap == null) {return Set.of();}
        return longSessionMap.keySet();
    }

}